package org.example.aspect;

import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.example.annotation.RequestInfo;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.util.Map;

@Aspect
@Component
@Slf4j
public class RequestInfoAspect {
    // 定义切点：匹配方法上有注解 @RequestInfo 的方法
    @Pointcut("@annotation(requestInfo)")
    public void annotatedWithRequestInfo(RequestInfo requestInfo) {}

    // 定义切点：匹配 org.example.controller 包及其子包下的所有类的所有方法
    @Pointcut("execution(* org.example.controller..*(..))")
    public void inControllerPackage() {}

    // 对带有 @RequestInfo 注解的方法进行拦截
    @Before("annotatedWithRequestInfo(requestInfo)")
    public void doBeforeWithAnnotation(JoinPoint joinPoint, RequestInfo requestInfo) {
        handleRequest(joinPoint);
    }

    // 对 org.example.controller 包下的所有方法进行拦截
    @Before("inControllerPackage()")
    public void doBeforeInController(JoinPoint joinPoint) {
        handleRequest(joinPoint);
    }

    // 抽取公共逻辑
    private void handleRequest(JoinPoint joinPoint) {
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        String methodName = signature.getName();

        ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        if (servletRequestAttributes == null) {
            log.warn("can not get ServletRequestAttributes, methodName={}", methodName);
            return;
        }

        HttpServletRequest request = servletRequestAttributes.getRequest();
        String method = request.getMethod();
        Object[] args = joinPoint.getArgs();
        String params = "";

        String queryString = request.getQueryString();
        if (args.length > 0) {
            if ("POST".equals(method)) {
                Object object = args[0];
                params = object.toString();
            } else if ("GET".equals(method)) {
                params = queryString;
            }
        }

        log.info("Request URL:{}, HTTP_METHOD:{}, IP:{}, Params:{}", request.getRequestURL().toString(), method, request.getRemoteAddr(), params);
    }
}
